home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / program / freeli22.zip / FREELIB.DOC < prev    next >
Text File  |  1996-09-01  |  71KB  |  2,399 lines

  1. o─────────────────────────────────────────────────────────────────o
  2. │────────── FREELIB: The FREE Assembly Language Library ──────────│
  3. │────────────────────────── Version 2.2 ──────────────────────────│
  4. │──────────── Copyright (C) Sept. 1996  Tenie Remmel ─────────────│
  5. o─────────────────────────────────────────────────────────────────o
  6.  
  7. 1. Introduction ................................ Line 34
  8. 2. Terms of use/Legal disclaimer ............... Line 53
  9. 3. Processors, calling conventions ............. Line 74
  10. 4. Re-assembling ............................... Line 140
  11. 5. Program Syntax .............................. Line 169
  12. 6. Procedure Reference ......................... Line 242
  13.     Initialization and Exit .................... Line 244
  14.     File Access ................................ Line 268
  15.     Directory and Disk ......................... Line 414
  16.     Bit-File Access ............................ Line 482
  17.     Memory Management .......................... Line 593
  18.     String Input/Output ........................ Line 658
  19.     Formatted Output ........................... Line 738
  20.     Alphanumeric Conversion .................... Line 830
  21.     Long/Fixed-Point Arithmetic ................ Line 922
  22.     Trigonometry ............................... Line 1067
  23.     String Manipulation ........................ Line 1138
  24.     Memory-Block Manipulation .................. Line 1255
  25.     Searches and Sorts ......................... Line 1307
  26.     High-Res Text Mode ......................... Line 1418
  27.     VGA Graphics ............................... Line 1835
  28.     Virtual Memory (80386+) .................... Line 2028
  29.     Miscellaneous .............................. Line 2076
  30. 7. List of contributors ........................ Line 2222
  31. 8. History of changes .......................... Line 2238
  32. 9. Future additions, bug reporting ............. Line 2328
  33. 10. Example programs ........................... Line 2364
  34.  
  35.  
  36. 1.  Introduction.
  37.  
  38.   FREELIB is a library of 175 procedures that may be useful for
  39.   programming in assembly language.   As the name implies, this
  40.   is public domain, completely free for all non-commercial use.
  41.   If you find this library useful,  you are strongly encouraged
  42.   to contribute some of your own routines for possible addition
  43.   to FREELIB.  Full source code is included, so if you find any
  44.   bugs (!) and wish to make changes to any of the routines, you
  45.   can.  However, if you do make any improvements, please notify
  46.   the author,  so that FREELIB  can continue to be expanded and
  47.   improved. If you modify any part of this library, you may not
  48.   distribute it, for free or not, without prior permission from
  49.   the author (see below).
  50.  
  51.   Be sure to read the sections 2, 3 and 5 carefully,  including
  52.   the miscellaneous notes in section 3.
  53.  
  54.  
  55. 2.  Terms of use/Legal disclaimer.
  56.  
  57.   This software is hereby released into the public domain,  and
  58.   may  therefore  be freely  copied and distributed  within the
  59.   following restrictions:
  60.  
  61.       1).  It is distributed in its original,  unmodified form,
  62.            including all source code and documentation.
  63.  
  64.       2).  No fee is charged for use, copying or distribution.
  65.  
  66.       3).  The program may not be  included with other goods or
  67.            services supplied for a fee, unless specific written
  68.            permission to do so is obtained  in advance from the
  69.            author.  (E-mail: tjr19@mail.nwlink.com)
  70.  
  71.   This program is provided AS-IS without any warranty,  express
  72.   or implied, including  but not limited to warranty of fitness
  73.   for a particular purpose.
  74.  
  75.  
  76. 3.  Processors, calling conventions, string type, etc.
  77.  
  78.   FREELIB is programmed in 80186 assembly language.  This is to
  79.   ensure compatibility with as many computers as possible,  but
  80.   not sacrificing very much speed.  For many of the procedures,
  81.   an 80386 version is supplied.   The modules 386LIB1-2 are the
  82.   80386 versions of FREELIB1-2,  and the 386LIB.LIB file is the
  83.   library file for the 80386.
  84.  
  85.   FREELIB uses the  Pascal calling convention.   The parameters
  86.   are  pushed on the stack in order,  and the calling procedure
  87.   does not have to worry about stack cleanup.  This seems to be
  88.   the fastest method,  and it also helps in debugging... if the
  89.   wrong number of arguments are pushed to call a procedure, the
  90.   program will crash, which is much more obvious than the weird
  91.   results produced with the 'C' convention, etc.
  92.  
  93.   Notice that in the source code,  the syntax is given by a 'C'
  94.   style prototype.  Why a 'C' prototype?  Well, Pascal does not
  95.   have prototypes, and the 'C' prototype is useful to concisely
  96.   show the syntax of a procedure on one line.
  97.  
  98.   Misc. Notes:
  99.  
  100.     Many of the routines assume  DS = CS,  so make sure that this
  101.     is the case.   The program is intended to be a .COM file, but
  102.     .EXE files are OK as long as the DS = CS restriction is met.
  103.  
  104.     Do not use uninitialized data,  it will interfere with memory
  105.     management.  Use dynamically allocated memory instead.
  106.  
  107.     The fixed-point numbers are 16:16,  and signed.   The strings
  108.     are ASCIIZ  (null-terminated) strings,  like in C.   The long
  109.     integers can be either signed or unsigned, depending on which
  110.     multiply, divide and shift you use.
  111.  
  112.     When clock  timings are given,  they will always  include the
  113.     call/return, and exclude the argument pushes.
  114.  
  115.     Even though some  procedures require a character argument,  a
  116.     word-sized value must still be pushed:  it is not possible to
  117.     push a byte value.
  118.  
  119.     The files TEXT???.INC are not for including in your programs;
  120.     they are internally used by the High-Res Textmode routines in
  121.     the file FREELIB3.ASX.
  122.  
  123.     The colorset in High-Res Text Mode is different, see below.
  124.  
  125.     The graphics mode 320x400x256 is a ModeX.   The author of the
  126.     graphics procedures described it as 'dechain mode'.  I assume
  127.     that by this she meant that Chain-4 is off in this mode.
  128.  
  129.   Colorset in High-Res Text Mode:
  130.  
  131.   0 = Black         8 = Dark Gray
  132.   1 = Dark Green    9 = Red
  133.   2 = Green         10 = Orange
  134.   3 = Light Green   11 = Yellow
  135.   4 = True Blue     12 = Sky Blue
  136.   5 = Dark Purple   13 = Dark Blue
  137.   6 = Magenta       14 = Cyan
  138.   7 = Light Gray    15 = White
  139.  
  140.  
  141. 4.  Re-assembling FREELIB.
  142.  
  143.   A batch file (REDO.BAT) is provided for this purpose.   These
  144.   source files are .ASX files (ASsembly eXtended) which contain
  145.   multiple modules.  A utility (SPLIT.EXE) is included to split
  146.   the .ASX files.  SPLIT.C is the 'C' source to SPLIT.EXE.  The
  147.   batch file takes care of splitting the files. However, if you
  148.   wish to add a new .ASX file  (in addition to FREELIB1-3), you
  149.   must modify the batch file, otherwise it will be ignored.
  150.  
  151.   If you wish to  compile the 80386 version,  386LIB,  you must
  152.   use the REDO3.BAT batch file,  and use the  '386LIB*.*' files
  153.   instead of the 'FREELIB*.*' files (except FREELIB3.ASX).
  154.  
  155.   SPLIT outputs TLIB  command file codes.   SPLIT takes zero or
  156.   one arguments.  When run with no arguments, it produces codes
  157.   that end the command file.   When run with an argument  (what
  158.   it is doesn't matter)  it produces codes that continue to the
  159.   next file.
  160.  
  161.   In the .ASX files, a line starting with three tildes (~) that
  162.   are followed by a file name without extension will denote the
  163.   beginning of a new module.   Either make sure that all of the
  164.   module names start with 'C_' or modify the REDO.BAT file.  If
  165.   you put any .ASM  files with names starting with  'C_' in the
  166.   FREELIB directory, be warned: they will be deleted along with
  167.   the temporary .ASM files created by SPLIT.
  168.  
  169.  
  170. 5.  Program syntax for use with FREELIB.
  171.  
  172.   Your program should do a near call, or jump, to the 'startup'
  173.   procedure at the beginning. The main body of the program must
  174.   be in the procedure 'main', which must be declared public.
  175.  
  176.   On entry to main, the number of arguments is in CX and a list
  177.   of near pointers to the arguments is at offset DI.  DS and ES
  178.   both equal CS.  AX, BX, DX, SI, and BP are undefined.
  179.  
  180.   You must declare as  external all procedures  that you intend
  181.   to use.  One way to simplify this is with a macro:
  182.  
  183. ;──────────────────────────────────────
  184.  
  185. Macro       lcall p,a,b,c,d,e,f,g,h ;; library call
  186.  
  187.             ifnb a
  188.               push a                ;; if args, push first arg
  189.               lcall p,b,c,d,e,f,g,h ;; and recurse . . .
  190.             else
  191.               extrn p:near          ;; declare procedure
  192.               call p                ;; call procedure
  193.             endif
  194.  
  195. EndM
  196.  
  197. ;──────────────────────────────────────
  198.  
  199.   and then you would replace  'call' with  'lcall' when calling
  200.   library procedures.   However,  to use the  arguments feature
  201.   of this macro,  if an offset of a variable is used it must be
  202.   specified as 'offset(var)' instead of 'offset var', otherwise
  203.   the macro thinks it is two arguments.
  204.  
  205.   This is a skeleton program:
  206.  
  207. ;──────────────────────────────────────
  208.  
  209. Ideal                               ; ideal mode
  210.  
  211. Public      main                    ; declare main as public
  212. Extrn       startup:near            ; declare startup procedure
  213.  
  214. Macro       lcall p,a,b,c,d,e,f,g,h ;; library call
  215.  
  216.             ifnb a
  217.               push a                ;; if args, push first arg
  218.               lcall p,b,c,d,e,f,g,h ;; and recurse . . .
  219.             else
  220.               extrn p:near          ;; declare procedure
  221.               call p                ;; call procedure
  222.             endif
  223.  
  224. EndM
  225.  
  226. Model Tiny                          ; tiny model
  227. CodeSeg                             ; code segment
  228. Org 100h                            ; .COM file start
  229.  
  230. Start:      jmp startup             ; start up program
  231.  
  232. Proc        main                    ; main procedure
  233.  
  234.             ret                     ; return
  235.  
  236. EndP        main
  237.  
  238. End Start                           ; entry at 'Start'
  239.  
  240. ;──────────────────────────────────────
  241.  
  242.  
  243. 6.  Reference: Syntax and description of all FREELIB procedures.
  244.  
  245.   ─────────────────────────────────────────────────────────────
  246.   ──────────── Initialization and Exit Procedures ─────────────
  247.   ─────────────────────────────────────────────────────────────
  248.  
  249.   ────────── startup            Start program
  250.  
  251.     jmp startup
  252.  
  253.     This procedure must be jumped to at the beginning of
  254.     your program.  (See Section 5.)
  255.  
  256.     This procedure calls 'main'.  It also does internal
  257.     initialization, and sets null Ctrl-C and divide-error
  258.     handlers.
  259.  
  260.   ────────── exit               Exit program
  261.  
  262.     push retcode
  263.     call exit
  264.  
  265.     This procedure exits your program with a return code.
  266.     If exit is not used, the return code is the value of
  267.     AX on return from main.
  268.  
  269.   ─────────────────────────────────────────────────────────────
  270.   ────────────────────── File Procedures ──────────────────────
  271.   ─────────────────────────────────────────────────────────────
  272.  
  273.   ────────── fopen              Open file
  274.  
  275.     push offset filename
  276.     push filemode
  277.     call fopen
  278.     ; AX = handle
  279.  
  280.     This procedure opens a buffered file.  The handle is
  281.     returned in AX.  This handle is NOT a DOS handle.
  282.     If it is used as such, the results are unpredictable.
  283.  
  284.     The file modes are:
  285.  
  286.     0     Open Read-Only (open if it exists, fail if not)
  287.     1     Open/Create (open if it exists, create if not)
  288.     2     Open Only (open if it exists, fail if not)
  289.     3     Create/Truncate (truncate if it exists, create if not)
  290.     4     Create Only (fail if it exists, create if not)
  291.  
  292.   ────────── fclose             Close file
  293.  
  294.     push handle
  295.     call fclose
  296.  
  297.     This procedure closes a buffered file.  If the handle
  298.     is invalid, nothing happens.
  299.  
  300.   ────────── fgetc              Get char from file
  301.  
  302.     push handle
  303.     call fgetc
  304.     ; AX = char
  305.  
  306.     This procedure gets a character from a buffered file.
  307.     If the end of file is reached or an error occurs, -1
  308.     is returned.
  309.  
  310.   ────────── fputc              Put char to file
  311.  
  312.     push handle
  313.     push char
  314.     call fputc
  315.     ; AX = return code
  316.  
  317.     This procedure puts a character to a buffered file.
  318.     If the end of file is reached or an error occurs, -1
  319.     is returned, otherwise the character is returned.
  320.  
  321.   ────────── fread              Read block from file
  322.  
  323.     push handle
  324.     push size
  325.     push offset buf
  326.     call fread
  327.     ; AX = return code
  328.  
  329.     This procedure reads a block from a buffered file.  The
  330.     number of characters read is returned.  If this is less
  331.     than the requested size, the end of file was reached or
  332.     an error occured.
  333.  
  334.   ────────── fwrite             Write block to file
  335.  
  336.     push handle
  337.     push size
  338.     push offset buf
  339.     call fwrite
  340.     ; AX = return code
  341.  
  342.     This procedure writes a block to a buffered file.  The
  343.     number of characters written is returned.  If this is
  344.     less than the requested size, an error occured.
  345.  
  346.   ────────── fseek              Set file pointer
  347.  
  348.     push handle
  349.     push pos_hi
  350.     push pos_lo
  351.     push mode
  352.     call fseek
  353.     ; AX = return code
  354.  
  355.     This procedure sets the position of the file pointer.
  356.     The position is a long integer.  If an error occurs, 0
  357.     is returned, otherwise a nonzero value is returned.
  358.  
  359.     The seek modes are:
  360.  
  361.     0     Seek from beginning of file
  362.     1     Seek from current position
  363.     2     Seek from end of file
  364.  
  365.   ────────── ftell              Get file pointer
  366.  
  367.     push handle
  368.     call ftell
  369.     ; DX:AX = file pointer
  370.  
  371.     This procedure returns the position of the file pointer.
  372.  
  373.   ────────── fsetbuf            Set file buffer size
  374.  
  375.     push size
  376.     call fsetbuf
  377.  
  378.     This procedure sets the file buffer size.  It does not
  379.     affect currently open files.  It only affects files that
  380.     are opened after this call.  The default size is 512
  381.     bytes, but it may be set to from 128 to 32752 bytes.
  382.     If the size requested is greater than 32768, the high
  383.     bit is simply masked off, f.i. 33024 will produce 256.
  384.  
  385.   ────────── ftrunc             Truncate file
  386.  
  387.     push handle
  388.     call ftrunc
  389.     ; AX = return code
  390.  
  391.     This procedure truncates a buffered file at the current
  392.     position.  If an error occurs, 0 is returned, otherwise
  393.     a nonzero value is returned.
  394.  
  395.   ────────── fdel               Delete file
  396.  
  397.     push offset filename
  398.     call fdel
  399.     ; AX = return code
  400.  
  401.     This procedure deletes a file.  If an error occurs, 0 is
  402.     returned, otherwise a nonzero value is returned.
  403.  
  404.   ────────── fmove              Move/Rename file
  405.  
  406.     push offset oldname
  407.     push offset newname
  408.     call fmove
  409.     ; AX = return code
  410.  
  411.     This procedure moves and/or renames a file.  If an error
  412.     occurs, 0 is returned, otherwise a nonzero value is
  413.     returned.
  414.  
  415.   ─────────────────────────────────────────────────────────────
  416.   ─────────────── Directory and Disk Procedures ───────────────
  417.   ─────────────────────────────────────────────────────────────
  418.  
  419.   ────────── mkdir              Create Directory
  420.  
  421.     push offset dirname
  422.     call mkdir
  423.     ; AX = return code
  424.  
  425.     This procedure creates a directory.  If an error occurs,
  426.     0 is returned, otherwise a nonzero value is returned.
  427.  
  428.   ────────── rmdir              Remove Directory
  429.  
  430.     push offset dirname
  431.     call rmdir
  432.     ; AX = return code
  433.  
  434.     This procedure deletes a directory.  If an error occurs,
  435.     0 is returned, otherwise a nonzero value is returned.
  436.  
  437.   ────────── setdir             Set Current Directory
  438.  
  439.     push offset dirname
  440.     call setdir
  441.     ; AX = return code
  442.  
  443.     This procedure sets the current directory.  If an error
  444.     occurs, 0 is returned, otherwise a nonzero value is
  445.     returned.
  446.  
  447.   ────────── getdir             Get Current Directory
  448.  
  449.     push offset buffer
  450.     call getdir
  451.  
  452.     This procedure returns the current directory.
  453.     The full path is returned in 'buffer'.
  454.  
  455.   ────────── setdrive           Set Current Drive
  456.  
  457.     push dr_num
  458.     call setdrive
  459.  
  460.     This procedure sets the current drive.  The numbers are
  461.     the same as the DOS drive numbers.  (0 = default, 1 = A,
  462.     2 = B, 3 = C, etc.)
  463.  
  464.   ────────── getdrive           Get Current Drive
  465.  
  466.     call getdrive
  467.     ; AX = drive number
  468.  
  469.     This procedure returns the current drive.  The numbers
  470.     are the same as the DOS drive numbers.  (0 = default,
  471.     1 = A, 2 = B, 3 = C, etc.)
  472.  
  473.   ────────── getdfree           Get Free Disk Space
  474.  
  475.     push dr_num
  476.     call getdfree
  477.     ; DX:AX = amount of free space
  478.  
  479.     This procedure returns the amount of free disk space
  480.     on a drive.  The number returned is in bytes.
  481.  
  482.  
  483.   ─────────────────────────────────────────────────────────────
  484.   ─────────────── Bit-Oriented File Procedures ────────────────
  485.   ─────────────────────────────────────────────────────────────
  486.  
  487.   ────────── bfopen             Open Bit-File
  488.  
  489.     push offset filename
  490.     push filemode
  491.     call bfopen
  492.     ; AX = handle
  493.  
  494.     This procedure opens a bit-oriented file.  The handle
  495.     is returned in AX.  This handle is NOT a DOS handle, or
  496.     a standard FREELIB handle.  If it is used as such, the
  497.     results are unpredictable.
  498.  
  499.     Bit-oriented files are useful for many compression and
  500.     encryption methods, and simply to reduce space, say, by
  501.     writing 9 bits each for data that ranges from 0 to 500
  502.     instead of using a word (16 bits) to store it.
  503.  
  504.     The file modes are:
  505.  
  506.     0     Open Input Bit File (read-only)
  507.     1     Open Output Bit File (write-only)
  508.  
  509.   ────────── bfclose            Close Bit-File
  510.  
  511.     push handle
  512.     call bfclose
  513.  
  514.     This procedure closes a bit-oriented file.
  515.  
  516.   ────────── getbit             Get Bit from Bit-File
  517.  
  518.     push handle
  519.     call getbit
  520.     ; AX = bit (0 or 1)
  521.  
  522.     This procedure returns the next bit from a bit-oriented
  523.     file in input mode.  The bit is returned in AX.  If the
  524.     file is in output mode, nothing happens, but the return
  525.     value is undefined.
  526.  
  527.   ────────── putbit             Put Bit to Bit-File
  528.  
  529.     push handle
  530.     push bit
  531.     call putbit
  532.  
  533.     This procedure outputs a bit to a bit-oriented file in
  534.     output mode.  The bit is considered a 0 if the number is
  535.     zero, otherwise it is considered a 1.  If the file is in
  536.     input mode, nothing happens.
  537.  
  538.   ────────── getbits            Get Bits from Bit-File
  539.  
  540.     push handle
  541.     push count
  542.     call getbits
  543.     ; AX = value
  544.  
  545.     This procedure inputs a value of size 'count' bits from
  546.     a bit-oriented file.  The value is returned in AX.  If
  547.     the file is in output mode, nothing happens, but the
  548.     return value is undefined.
  549.  
  550.   ────────── putbits            Put Bits to Bit-File
  551.  
  552.     push handle
  553.     push value
  554.     push count
  555.     call putbits
  556.  
  557.     This procedure outputs the low 'count' bits of 'value'
  558.     to a bit-oriented file.  The bits are output in order
  559.     from MSB to LSB.  If the file is in input mode, nothing
  560.     happens.
  561.  
  562.   ────────── getcode            Get Code from Bit-File
  563.  
  564.     push handle
  565.     push max
  566.     call getcode
  567.     ; AX = value
  568.  
  569.     This procedure inputs an optimal binary code for a value
  570.     less than 'max' from a bit-oriented file.  The value is
  571.     returned in AX.  If the file is in output mode, nothing
  572.     happens, but the return value is undefined.  If 'max' is
  573.     specified as 0 or 1, the results will be unpredictable.
  574.  
  575.     An optimal binary code saves a bit versus the standard
  576.     one for some values.  It can be useful for saving space.
  577.  
  578.   ────────── putcode            Put Code to Bit-File
  579.  
  580.     push handle
  581.     push value
  582.     push max
  583.     call putcode
  584.  
  585.     This procedure outputs the optimal binary code for a
  586.     value less than 'max' to a bit-oriented file.  If the
  587.     file is in input mode, nothing happens.  If 'max' is
  588.     specified as 0 or 1, the results will be unpredictable.
  589.  
  590.     An optimal binary code saves a bit versus the standard
  591.     one for some values.  It can be useful for saving space.
  592.  
  593.  
  594.   ─────────────────────────────────────────────────────────────
  595.   ───────────────── Memory Manager Procedures ─────────────────
  596.   ─────────────────────────────────────────────────────────────
  597.  
  598.   ────────── allocmem           Allocate Memory
  599.  
  600.     push size
  601.     call allocmem
  602.     ; AX = pointer
  603.  
  604.     This procedure allocates memory.  If there was not a big
  605.     enough block of memory, -1 is returned, otherwise a
  606.     pointer to the block of memory is returned.
  607.  
  608.   ────────── freemem            Free Memory
  609.  
  610.     push ptr
  611.     call freemem
  612.  
  613.     This procedure frees memory.  If 'ptr' does not point to
  614.     a valid block, nothing happens.  If free blocks abut the
  615.     block to be freed, they are coalesced.
  616.  
  617.   ────────── getmfree           Get Free Memory
  618.  
  619.     call getmfree
  620.     ; AX = size of largest free block
  621.  
  622.     This procedure returns the size of the largest free
  623.     block of memory.  If there are no free blocks, 0 is
  624.     returned.
  625.  
  626.   ────────── faralloc           Allocate Far Memory
  627.  
  628.     push size
  629.     call faralloc
  630.     ; AX = segment
  631.  
  632.     This procedure allocates far memory.  If there was not
  633.     a big enough block of memory, -1 is returned, otherwise
  634.     the segment of the memory block is returned.  The size
  635.     must be specified in paragraphs (16 bytes each).  This
  636.     calls the DOS allocate memory service.
  637.  
  638.   ────────── farfree            Free Far Memory
  639.  
  640.     push seg
  641.     call freemem
  642.  
  643.     This procedure frees far memory.  If 'seg' is not the
  644.     segment of a valid memory block, the results will be
  645.     undefined.  If free blocks abut the block to be freed,
  646.     they are coalesced.  This calls the DOS free memory
  647.     service.
  648.  
  649.   ────────── getfarfree         Get Free Far Memory
  650.  
  651.     call getfarfree
  652.     ; AX = size of largest free block
  653.  
  654.     This procedure returns the size of the largest free
  655.     block of far memory.  If there are no free blocks, 0
  656.     is returned.
  657.  
  658.  
  659.   ─────────────────────────────────────────────────────────────
  660.   ───────────────── Put/Get String Procedures ─────────────────
  661.   ─────────────────────────────────────────────────────────────
  662.  
  663.   ────────── puts               Put String
  664.  
  665.     push offset string
  666.     call puts
  667.  
  668.     This procedure writes a string to the screen.  If the
  669.     STDOUT handle is redirected, this still works.  The
  670.     string is output literally, using Int 29h.
  671.  
  672.   ────────── fputs              Put String to File
  673.  
  674.     push handle
  675.     push offset string
  676.     call fputs
  677.  
  678.     This procedure writes a string to a file.  If an error
  679.     occurs, -1 is returned, otherwise a nonzero value is
  680.     returned.  The handle is a FREELIB handle, not a DOS
  681.     handle.
  682.  
  683.   ────────── xputs              Put String, Generalized
  684.  
  685.     push offset outfunc
  686.     push offset string
  687.     call xputs
  688.  
  689.     This procedure outputs a string using a user-defined
  690.     function.  The function must take one word argument,
  691.     the character to output, save all registers, and return
  692.     with a 'Ret 2' to clean up the stack.
  693.  
  694.   ────────── gets               Get String
  695.  
  696.     push offset buffer
  697.     push max
  698.     call gets
  699.  
  700.     This procedure inputs a string from the keyboard.  The
  701.     string of maximum 'max' chars will be put into 'buffer'.
  702.     Any excess characters will be discarded.  This procedure
  703.     allows simple editing using the <BkSp> key.
  704.  
  705.   ────────── fgets              Get String from File
  706.  
  707.     push handle
  708.     push offset buffer
  709.     push max
  710.     call fgets
  711.     ; AX = return code
  712.  
  713.     This procedure reads a line from a file.  The string of
  714.     maximum 'max' chars will be read into 'buffer'.  The
  715.     line must end with a CR/LF pair.  An entire line will be
  716.     input even if it exceeds 'max' characters.  Any excess
  717.     will be discarded.  The handle is a FREELIB handle, not
  718.     a DOS handle.  If the end of file is reached, -1 is
  719.     returned, otherwise 0 is returned.
  720.  
  721.   ────────── xgets              Get String, Generalized
  722.  
  723.     push offset outfunc
  724.     push offset buffer
  725.     push max
  726.     push terminator
  727.     call xgets
  728.  
  729.     This procedure reads a logical line using a user-defined
  730.     function.  The function must take zero arguments and
  731.     return in AL the character input.  No register except
  732.     AX may be changed.  The value 'terminator' must be
  733.     returned on end of logical line.  The string of maximum
  734.     'max' chars will be read into 'buffer'.  An entire
  735.     logical line will be input even if it exceeds 'max'
  736.     characters.  Any excess will be discarded.
  737.  
  738.  
  739.   ─────────────────────────────────────────────────────────────
  740.   ───────────── Formatted String Print Procedures ─────────────
  741.   ─────────────────────────────────────────────────────────────
  742.  
  743.   ────────── printf             Print Formatted String
  744.  
  745.     push offset fmtstr
  746.     push offset arglist
  747.     call printf
  748.  
  749.     This procedure prints a formatted string to the screen.
  750.     It is similar to the 'printf()' in 'C'.  In the format
  751.     string, the '%' character is special.  The '%' character
  752.     can be followed by the following characters, which
  753.     indicate what type of argument to print:
  754.  
  755.       %d        Integer
  756.       %x        Hex integer
  757.       %s        String
  758.       %c        Character
  759.       %ld       Long integer
  760.       %lx       Long hex integer
  761.  
  762.     The parameter 'arglist' is a list of arguments, in
  763.     order.  Their types are taken from the format string.
  764.     If the wrong type is specified in the format string,
  765.     printf has no way of knowing, so the results will be
  766.     unpredictable.
  767.  
  768.     Example of using printf:
  769.  
  770. ;──────────────────────────────────────
  771.  
  772.             ...
  773.  
  774. FmtStr      db '%d %s %c %lx',0
  775.  
  776. ArgList     dw 15600
  777.             db 'This is a string',0
  778.             db 'X'
  779.             dd 1A2B3C4Dh
  780.  
  781.             ...
  782.  
  783.             push offset FmtStr
  784.             push offset ArgList
  785.             call printf
  786.  
  787.             ...
  788.  
  789. ;──────────────────────────────────────
  790.  
  791.     This example will output '15600 This is a string X 1A2B3C4D'.
  792.  
  793.   ────────── fprintf            Print Formatted String to File
  794.  
  795.     push handle
  796.     push offset fmtstr
  797.     push offset arglist
  798.     call printf
  799.  
  800.     This procedure prints a formatted string to a file.  It
  801.     works the same way printf does.  See 'printf' for more
  802.     information.
  803.  
  804.   ────────── sprintf            Print Formatted String to String
  805.  
  806.     push offset dest_str
  807.     push offset fmtstr
  808.     push offset arglist
  809.     call printf
  810.  
  811.     This procedure prints a formatted string to a string.
  812.     The string output will be null terminated.  This
  813.     procedure works the same way printf does.  See 'printf'
  814.     for more information.
  815.  
  816.   ────────── xprintf            Print Formatted String, Generalized
  817.  
  818.     push offset outfunc
  819.     push offset fmtstr
  820.     push offset arglist
  821.     call printf
  822.  
  823.     This procedure prints a formatted string using a user
  824.     defined function.  The function must take one word
  825.     argument, the character to output, save all registers,
  826.     and return with a 'Ret 2' to clean up the stack.  This
  827.     procedure works the same way printf does.  See 'printf'
  828.     for more information.
  829.  
  830.  
  831.   ─────────────────────────────────────────────────────────────
  832.   ──────────── Alphanumeric Conversion Procedures ─────────────
  833.   ─────────────────────────────────────────────────────────────
  834.  
  835.   ────────── atoi               Convert String to Integer
  836.  
  837.     push offset string
  838.     call atoi
  839.     ; AX = result
  840.  
  841.     This procedure converts a string to an integer.  It
  842.     recognizes the '-' and '+' signs, but it will stop on
  843.     any other non-digit.  The integer corresponding to the
  844.     string is returned.  If the result overflows, the low
  845.     16 bits of the result are returned.
  846.  
  847.   ────────── atol               Convert String to Long
  848.  
  849.     push offset string
  850.     call atol
  851.     ; DX:AX = result
  852.  
  853.     This procedure converts a string to a long integer.
  854.     It recognizes the '-' and '+' signs, but it will stop on
  855.     any other non-digit.  The long integer corresponding to
  856.     the string is returned.  If the result overflows, the
  857.     low 32 bits of the result are returned.
  858.  
  859.   ────────── itoa               Convert Integer to String
  860.  
  861.     push number
  862.     push offset buffer
  863.     call itoa
  864.  
  865.     This procedure converts an integer to a string.  On
  866.     return, 'buffer' will contain the decimal representation
  867.     of 'number'.  The string will be null terminated.  If
  868.     the number is negative, this will be handled correctly.
  869.  
  870.   ────────── ltoa               Convert Long to String
  871.  
  872.     push num_hi
  873.     push num_lo
  874.     push offset buffer
  875.     call ltoa
  876.  
  877.     This procedure converts a long integer to a string.  On
  878.     return, 'buffer' will contain the decimal representation
  879.     of the number.  The string will be null terminated.  If
  880.     the number is negative, this will be handled correctly.
  881.  
  882.   ────────── atofix             Convert String to Fixed-Point
  883.  
  884.     push offset string
  885.     call atofix
  886.     ; DX:AX = result
  887.  
  888.     This procedure converts a string to a fixed-point
  889.     number.  Itrecognizes the '-' and '+' signs and the
  890.     decimal point, but it will stop on any other non-digit.
  891.     The fixed-point number corresponding to the string is
  892.     returned.  If the result overflows, the value returned
  893.     will have the correct fractional part, and the integer
  894.     part will be the low 16 bits of the true value.
  895.  
  896.   ────────── fixtoa             Convert Fixed-Point to String
  897.  
  898.     push num_hi
  899.     push num_lo
  900.     push offset buffer
  901.     call fixtoa
  902.  
  903.     This procedure converts a fixed-point number to a
  904.     string.  On return, 'buffer' will contain the decimal
  905.     representation of the number.  The string will be null
  906.     terminated.  If the number is negative, this will be
  907.     handled correctly.  Fractions will also be handled
  908.     correctly.
  909.  
  910.   ────────── roman              Convert Integer to Roman Numerals
  911.  
  912.     push number
  913.     push offset buffer
  914.     call roman
  915.  
  916.     This procedure converts an integer to Roman Numerals.
  917.     On return, 'buffer' will contain the Roman Numeral
  918.     representation of 'number'.  The string will be null
  919.     terminated.  If the number is negative or zero, a null
  920.     string will be output.
  921.  
  922.  
  923.   ─────────────────────────────────────────────────────────────
  924.   ────── Long Integer/Fixed Point Arithmetic Procedures ───────
  925.   ─────────────────────────────────────────────────────────────
  926.  
  927.   ────────── ldiv               Long Divide
  928.  
  929.     push num1_hi
  930.     push num1_lo
  931.     push num2_hi
  932.     push num2_lo
  933.     call ldiv
  934.     ; DX:AX = result
  935.  
  936.     This procedure divides unsigned long integers.
  937.     It divides 'num1' by 'num2'.
  938.  
  939.   ────────── lidiv              Long Divide, Signed
  940.  
  941.     push num1_hi
  942.     push num1_lo
  943.     push num2_hi
  944.     push num2_lo
  945.     call lidiv
  946.     ; DX:AX = result
  947.  
  948.     This procedure divides signed long integers.
  949.     It divides 'num1' by 'num2'.
  950.  
  951.   ────────── lmul               Long Multiply
  952.  
  953.     push num1_hi
  954.     push num1_lo
  955.     push num2_hi
  956.     push num2_lo
  957.     call lmul
  958.     ; DX:AX = result
  959.  
  960.     This procedure multiplies unsigned long integers.
  961.     It takes 70 clock ticks on a 486, including the
  962.     call/return but not the argument pushes.
  963.  
  964.   ────────── limul              Long Multiply, Signed
  965.  
  966.     push num1_hi
  967.     push num1_lo
  968.     push num2_hi
  969.     push num2_lo
  970.     call limul
  971.     ; DX:AX = result
  972.  
  973.     This procedure multiplies signed long integers.
  974.     It takes 89-97 clock ticks on a 486, including the
  975.     call/return but not the argument pushes.
  976.  
  977.   ────────── lmod               Long Modulo
  978.  
  979.     push num1_hi
  980.     push num1_lo
  981.     push num2_hi
  982.     push num2_lo
  983.     call lmod
  984.     ; DX:AX = result
  985.  
  986.     This procedure does the modulo operation on unsigned
  987.     long integers.   It divides 'num1' by 'num2' and returns
  988.     the remainder.
  989.  
  990.   ────────── limod              Long Modulo, Signed
  991.  
  992.     push num1_hi
  993.     push num1_lo
  994.     push num2_hi
  995.     push num2_lo
  996.     call limod
  997.     ; DX:AX = result
  998.  
  999.     This procedure does the modulo operation on signed long
  1000.     integers.   It divides 'num1' by 'num2' and returns the
  1001.     remainder.
  1002.  
  1003.   ────────── lshl               Long Shift Left
  1004.  
  1005.     push num_hi
  1006.     push num_lo
  1007.     push dist
  1008.     call lshl
  1009.     ; DX:AX = result
  1010.  
  1011.     This procedure shifts a long integer to the left.
  1012.     It shifts 'num' by 'dist', and takes 37 clock
  1013.     ticks on a 486, including the call/return but not
  1014.     the argument pushes.
  1015.  
  1016.   ────────── lshr               Long Shift Right
  1017.  
  1018.     push num_hi
  1019.     push num_lo
  1020.     push dist
  1021.     call lshr
  1022.     ; DX:AX = result
  1023.  
  1024.     This procedure shifts an unsigned long integer to the
  1025.     right.  It shifts 'num' by 'dist', and takes 37 clock
  1026.     ticks on a 486, including the call/return but not
  1027.     the argument pushes.
  1028.  
  1029.   ────────── lsar               Long Shift Right, Signed
  1030.  
  1031.     push num_hi
  1032.     push num_lo
  1033.     push dist
  1034.     call lsar
  1035.     ; DX:AX = result
  1036.  
  1037.     This procedure shifts a signed long integer to the
  1038.     right.  It shifts 'num' by 'dist', and takes 39 clock
  1039.     ticks on a 486, including the call/return but not
  1040.     the argument pushes.
  1041.  
  1042.   ────────── fixmul             Fixed-Point Multiply
  1043.  
  1044.     push num1_hi
  1045.     push num1_lo
  1046.     push num2_hi
  1047.     push num2_lo
  1048.     call fixmul
  1049.     ; DX:AX = result
  1050.  
  1051.     This procedure multiplies fixed-point numbers.
  1052.     It takes 101-109 clock ticks on a 486, including
  1053.     the call/return but not the argument pushes.
  1054.  
  1055.   ────────── fixdiv             Fixed-Point Divide
  1056.  
  1057.     push num1_hi
  1058.     push num1_lo
  1059.     push num2_hi
  1060.     push num2_lo
  1061.     call fixdiv
  1062.     ; DX:AX = result
  1063.  
  1064.     This procedure divides fixed-point numbers.
  1065.     It divides 'num1' by 'num2'.
  1066.  
  1067.  
  1068.   ─────────────────────────────────────────────────────────────
  1069.   ───────────────── Trigonometric Procedures ──────────────────
  1070.   ─────────────────────────────────────────────────────────────
  1071.  
  1072.   ────────── sine               Sine
  1073.  
  1074.     push num_hi
  1075.     push num_lo
  1076.     call sine
  1077.     ; DX:AX = result
  1078.  
  1079.     This procedure calculates the trigonometric sine of
  1080.     'num'.  It operates on fixed-point numbers.  The input
  1081.     value should be in radians.
  1082.  
  1083.   ────────── cosine             Cosine
  1084.  
  1085.     push num_hi
  1086.     push num_lo
  1087.     call cosine
  1088.     ; DX:AX = result
  1089.  
  1090.     This procedure calculates the trigonometric cosine of
  1091.     'num'.  It operates on fixed-point numbers.  The input
  1092.     value should be in radians.
  1093.  
  1094.   ────────── tangent            Tangent
  1095.  
  1096.     push num_hi
  1097.     push num_lo
  1098.     call tangent
  1099.     ; DX:AX = result
  1100.  
  1101.     This procedure calculates the trigonometric tangent of
  1102.     'num'.  It operates on fixed-point numbers.  The input
  1103.     value should be in radians.
  1104.  
  1105.   ────────── cotangent          Cotangent
  1106.  
  1107.     push num_hi
  1108.     push num_lo
  1109.     call cotangent
  1110.     ; DX:AX = result
  1111.  
  1112.     This procedure calculates the trigonometric cotangent of
  1113.     'num'.  It operates on fixed-point numbers.  The input
  1114.     value should be in radians.
  1115.  
  1116.   ────────── secant             Secant
  1117.  
  1118.     push num_hi
  1119.     push num_lo
  1120.     call secant
  1121.     ; DX:AX = result
  1122.  
  1123.     This procedure calculates the trigonometric secant of
  1124.     'num'.  It operates on fixed-point numbers.  The input
  1125.     value should be in radians.
  1126.  
  1127.   ────────── cosecant           Cosecant
  1128.  
  1129.     push num_hi
  1130.     push num_lo
  1131.     call cosecant
  1132.     ; DX:AX = result
  1133.  
  1134.     This procedure calculates the trigonometric cosecant of
  1135.     'num'.  It operates on fixed-point numbers.  The input
  1136.     value should be in radians.
  1137.  
  1138.  
  1139.   ─────────────────────────────────────────────────────────────
  1140.   ───────────────────── String Procedures ─────────────────────
  1141.   ─────────────────────────────────────────────────────────────
  1142.  
  1143.   ────────── strlen             String Length
  1144.  
  1145.     push offset string
  1146.     call strlen
  1147.     ; AX = length
  1148.  
  1149.     This procedure returns the length of a string, not
  1150.     including the null terminator.
  1151.  
  1152.   ────────── strcpy             Copy String
  1153.  
  1154.     push offset dest_str
  1155.     push offset src_str
  1156.     call strcpy
  1157.  
  1158.     This procedure copies 'src_str' to 'dest_str', including
  1159.     the null terminator.  There is no checking to see if the
  1160.     string fits, so be careful.
  1161.  
  1162.   ────────── strcat             Concatenate Strings
  1163.  
  1164.     push offset dest_str
  1165.     push offset src_str
  1166.     call strcat
  1167.  
  1168.     This procedure concatenates 'src_str' onto 'dest_str',
  1169.     including the null terminator.  There is no checking to
  1170.     see if the string fits, so be careful.
  1171.  
  1172.   ────────── strcmp             Compare Strings
  1173.  
  1174.     push offset string1
  1175.     push offset string2
  1176.     call strcmp
  1177.     ; AX  = return value
  1178.  
  1179.     This procedure compares 'string1' and 'string2'.  If
  1180.     'string2' is lexicographically greater, a negative value
  1181.     is returned.  If 'string1' is greater, a positive value
  1182.     is returned.  If they are equal, zero is returned.
  1183.  
  1184.   ────────── stricmp            Compare Strings, Case Insensitive
  1185.  
  1186.     push offset string1
  1187.     push offset string2
  1188.     call stricmp
  1189.     ; AX  = return value
  1190.  
  1191.     This procedure compares 'string1' and 'string2'.  If
  1192.     'string2' is lexicographically greater, a negative value
  1193.     is returned.  If 'string1' is greater, a positive value
  1194.     is returned.  If they are equal, zero is returned.  This
  1195.     procedure differs from strcmp in that the compare is
  1196.     case insensitive.
  1197.  
  1198.   ────────── strchr             Search String for Char
  1199.  
  1200.     push offset string
  1201.     push char
  1202.     call strchr
  1203.     ; AX  = return value
  1204.  
  1205.     This procedure searches for 'char' in 'string'.  If the
  1206.     character is not found, -1 is returned, otherwise the
  1207.     position of the character in the string is returned.
  1208.  
  1209.   ────────── strstr             Search String for Substring
  1210.  
  1211.     push offset string
  1212.     push offset substr
  1213.     call strchr
  1214.     ; AX  = return value
  1215.  
  1216.     This procedure searches for 'substr' in 'string'.  If
  1217.     the substring is not found, -1 is returned, otherwise
  1218.     the position of the substring in the main string is
  1219.     returned.
  1220.  
  1221.   ────────── strlwr             Convert String to Lowercase
  1222.  
  1223.     push offset string
  1224.     call strlwr
  1225.  
  1226.     This procedure converts a string to lowercase.  Any
  1227.     character in the string that is already lowercase or
  1228.     that is not a letter will not be affected.
  1229.  
  1230.   ────────── strupr             Convert String to Uppercase
  1231.  
  1232.     push offset string
  1233.     call strupr
  1234.  
  1235.     This procedure converts a string to uppercase.  Any
  1236.     character in the string that is already uppercase or
  1237.     that is not a letter will not be affected.
  1238.  
  1239.   ────────── strltrim           Trim Leading Spaces
  1240.  
  1241.     push offset string
  1242.     call strltrim
  1243.  
  1244.     This procedure trims leading spaces from a string.  If
  1245.     there are no leading spaces, nothing happens.
  1246.  
  1247.   ────────── strrtrim           Trim Trailing Spaces
  1248.  
  1249.     push offset string
  1250.     call strrtrim
  1251.  
  1252.     This procedure trims trailing spaces from a string.  If
  1253.     there are no trailing spaces, nothing happens.
  1254.  
  1255.  
  1256.   ─────────────────────────────────────────────────────────────
  1257.   ────────────────── Memory Block Procedures ──────────────────
  1258.   ─────────────────────────────────────────────────────────────
  1259.  
  1260.   ────────── memcpy             Copy Memory Block
  1261.  
  1262.     push dest_offset
  1263.     push src_offset
  1264.     push length
  1265.     call memcpy
  1266.  
  1267.     This procedure copies a block of memory from
  1268.     'src_offset' to 'dest_offset'.  The block is of length
  1269.     'length'.  This procedure will work correctly if the
  1270.     blocks overlap.
  1271.  
  1272.   ────────── memset             Set Memory Block
  1273.  
  1274.     push mem_offset
  1275.     push length
  1276.     push byte
  1277.     call memset
  1278.  
  1279.     This procedure fills a block of memory of length
  1280.     'length' at 'mem_offset' with 'byte'.
  1281.  
  1282.   ────────── memcmp             Compare Memory Blocks
  1283.  
  1284.     push dest_offset
  1285.     push src_offset
  1286.     push length
  1287.     call memcmp
  1288.     ; AX = return code
  1289.  
  1290.     This procedure compares two blocks of memory at offsets
  1291.     'src_offset' and 'dest_offset'.  The blocks are of
  1292.     length 'length'.  If they are equal, 1 is returned,
  1293.     otherwise 0 is returned.
  1294.  
  1295.   ────────── memchr             Search Memory Block
  1296.  
  1297.     push mem_offset
  1298.     push length
  1299.     push byte
  1300.     call memchr
  1301.  
  1302.     This procedure searches a block of memory of length
  1303.     'length' at 'src_offset' for 'byte'.  If the byte is
  1304.     found, its position within the block is returned,
  1305.     otherwise -1 is returned.
  1306.  
  1307.  
  1308.   ─────────────────────────────────────────────────────────────
  1309.   ──────────────── Search and Sort Procedures ─────────────────
  1310.   ─────────────────────────────────────────────────────────────
  1311.  
  1312.   ────────── isearch            Search Array of Integers
  1313.  
  1314.     push offset array
  1315.     push size
  1316.     push elem
  1317.     call isearch
  1318.     ; AX = return code
  1319.  
  1320.     This procedure searches an array of integers of size
  1321.     'size' for 'elem'.  This procedure assumes that the
  1322.     array is sorted.  If the element is found, its position
  1323.     in the array is returned, otherwise -1 is returned.
  1324.  
  1325.   ────────── lsearch            Search Array of Longs
  1326.  
  1327.     push offset array
  1328.     push size
  1329.     push elem_hi
  1330.     push elem_lo
  1331.     call lsearch
  1332.     ; AX = return code
  1333.  
  1334.     This procedure searches an array of long integers of
  1335.     size 'size' for 'elem'.  This procedure assumes that the
  1336.     array is sorted.  If the element is found, its position
  1337.     in the array is returned, otherwise -1 is returned.
  1338.  
  1339.   ────────── ssearch            Search Array of Strings
  1340.  
  1341.     push offset array
  1342.     push size
  1343.     push offset elem
  1344.     call ssearch
  1345.     ; AX = return code
  1346.  
  1347.     This procedure searches an array of strings of size
  1348.     'size' for 'elem'.  This procedure assumes that the
  1349.     array is sorted.  If the element is found, its position
  1350.     in the array is returned, otherwise -1 is returned.
  1351.  
  1352.   ────────── xsearch            Search Array, Generalized
  1353.  
  1354.     push offset array
  1355.     push size
  1356.     push offset elem
  1357.     push offset cmpfunc
  1358.     call xsearch
  1359.     ; AX = return code
  1360.  
  1361.     This procedure searches an array of pointers of size
  1362.     'size' for 'elem'.  It assumes that the array is sorted.
  1363.     If the element is found, its position in the array is
  1364.     returned, otherwise -1 is returned.
  1365.  
  1366.     This procedure uses a user-defined function.  The
  1367.     function must take two word-sized pointer arguments.
  1368.     It must return the result of the comparison in AX so
  1369.     that a negative value indicates less, a positive value
  1370.     indicates greater, and zero indicates equal, and it
  1371.     also should preserve all registers except for AX.
  1372.  
  1373.   ────────── isort              Sort Array of Integers
  1374.  
  1375.     push offset array
  1376.     push size
  1377.     call isort
  1378.  
  1379.     This procedure sorts an array of integers of size
  1380.     'size' in ascending order.
  1381.  
  1382.   ────────── lsort              Sort Array of Longs
  1383.  
  1384.     push offset array
  1385.     push size
  1386.     call lsort
  1387.  
  1388.     This procedure sorts an array of long integers of size
  1389.     'size' in ascending order.
  1390.  
  1391.   ────────── ssort              Sort Array of Strings
  1392.  
  1393.     push offset array
  1394.     push size
  1395.     call ssort
  1396.  
  1397.     This procedure sorts an array of strings of size
  1398.     'size' in alphabetical order.
  1399.  
  1400.   ────────── xsort              Sort Array, Generalized
  1401.  
  1402.     push offset array
  1403.     push size
  1404.     push offset cmpfunc
  1405.     call xsort
  1406.  
  1407.     This procedure sorts an array of pointers of size
  1408.     'size'.  This is the generalized sort procedure.
  1409.  
  1410.     This procedure uses a user-defined function.  The
  1411.     function must take two word-sized pointer arguments.
  1412.     It must return the result of the comparison in AX so
  1413.     that a negative value indicates less, a positive value
  1414.     indicates greater, and zero indicates equal, and it
  1415.     also should preserve all registers except for AX.
  1416.  
  1417.  
  1418.   ─────────────────────────────────────────────────────────────
  1419.   ─────────── High-Res Text Mode (90x34) Procedures ───────────
  1420.   ─────────────────────────────────────────────────────────────
  1421.  
  1422.   ────────── inittext           Initialize Text System
  1423.  
  1424.     call inittext
  1425.  
  1426.     This procedure initializes the High-Res Text Mode.
  1427.  
  1428.   ────────── closetext          Close Text System
  1429.  
  1430.     call closetext
  1431.  
  1432.     This procedure closes the High-Res Text system, and
  1433.     sets the standard text mode.
  1434.  
  1435.   ────────── clrscr             Clear Screen
  1436.  
  1437.     call clrscr
  1438.  
  1439.     This procedure clears the screen on the current video
  1440.     page.
  1441.  
  1442.   ────────── setwin             Set Window
  1443.  
  1444.     push x1 y1
  1445.     push x2 y2
  1446.     push rel_flag
  1447.     call setwin
  1448.  
  1449.     This procedure sets the clipping window.  'rel_flag'
  1450.     indicates whether coordinates will be relative to the
  1451.     window or not.
  1452.  
  1453.   ────────── clrwin             Clear Window
  1454.  
  1455.     call clrwin
  1456.  
  1457.     This procedure clears the current window.
  1458.  
  1459.   ────────── setpage            Set Video Page
  1460.  
  1461.     push page_num
  1462.     call setpage
  1463.  
  1464.     This procedure sets the current video page.  The page
  1465.     number must be between 0 and 5 (there are six pages).
  1466.  
  1467.   ────────── getpage            Get Video Page
  1468.  
  1469.     call getpage
  1470.     ; AX = current page
  1471.  
  1472.     This procedure returns the current video page.
  1473.  
  1474.   ────────── setcolor           Set Color
  1475.  
  1476.     push color
  1477.     call setcolor
  1478.  
  1479.     This procedure sets the current text color.  The color
  1480.     is a byte, 0XYh, where X is the background color and Y
  1481.     is the foreground color.
  1482.  
  1483.   ────────── getcolor           Get Color
  1484.  
  1485.     call getcolor
  1486.     ; AX = current color
  1487.  
  1488.     This procedure returns the current text color.
  1489.  
  1490.   ────────── box                Draw Box
  1491.  
  1492.     push x1 y1
  1493.     push x2 y2
  1494.     push char
  1495.     call box
  1496.  
  1497.     This procedure draws a box with character 'char'.  The
  1498.     box is clipped to the current window.
  1499.  
  1500.   ────────── sbox               Draw Style Box
  1501.  
  1502.     push x1 y1
  1503.     push x2 y2
  1504.     push style
  1505.     call sbox
  1506.  
  1507.     This procedure draws a style box.  The box is clipped
  1508.     to the current window.  Here is the list of styles:
  1509.  
  1510.     0       Blank
  1511.     1       Single Line
  1512.     2       Double Line
  1513.     3       Single/Double
  1514.     4       Double/Single
  1515.  
  1516.   ────────── fbox               Draw Filled Box
  1517.  
  1518.     push x1 y1
  1519.     push x2 y2
  1520.     push char
  1521.     call fbox
  1522.  
  1523.     This procedure draws a filled box with character 'char'.
  1524.     The box is clipped to the current window.
  1525.  
  1526.   ────────── hline              Draw Horizontal Line
  1527.  
  1528.     push x1 x2
  1529.     push y
  1530.     push char
  1531.     call hline
  1532.  
  1533.     This procedure draws a horizontal line with character
  1534.     'char'.  The line is clipped to the current window.
  1535.  
  1536.   ────────── vline              Draw Vertical Line
  1537.  
  1538.     push y1 y2
  1539.     push x
  1540.     push char
  1541.     call vline
  1542.  
  1543.     This procedure draws a vertical line with character
  1544.     'char'.  The line is clipped to the current window.
  1545.  
  1546.   ────────── hsline             Draw Horizontal Style Line
  1547.  
  1548.     push x1 x2
  1549.     push y
  1550.     push style
  1551.     call hsline
  1552.  
  1553.     This procedure draws a horizontal style line.  The line
  1554.     is clipped to the current window.  See the description
  1555.     for 'sbox' for a list of the styles.
  1556.  
  1557.   ────────── vsline             Draw Vertical Style Line
  1558.  
  1559.     push y1 y2
  1560.     push x
  1561.     push style
  1562.     call vsline
  1563.  
  1564.     This procedure draws a horizontal style line.  The line
  1565.     is clipped to the current window.  See the description
  1566.     for 'sbox' for a list of the styles.
  1567.  
  1568.   ────────── gotoxy             Set Cursor Position
  1569.  
  1570.     push x y
  1571.     call gotoxy
  1572.  
  1573.     This procedure sets the position of the cursor.  It is
  1574.     clipped to the current window.
  1575.  
  1576.   ────────── getx               Get Cursor X
  1577.  
  1578.     call getx
  1579.     ; AX = current X position
  1580.  
  1581.     This procedure returns the X position of the cursor.  If
  1582.     the window relative flag is set, the position will be
  1583.     relative to the current window.
  1584.  
  1585.   ────────── gety               Get Cursor Y
  1586.  
  1587.     call gety
  1588.     ; AX = current Y position
  1589.  
  1590.     This procedure returns the Y position of the cursor.  If
  1591.     the window relative flag is set, the position will be
  1592.     relative to the current window.
  1593.  
  1594.   ────────── setctype           Set Cursor Type
  1595.  
  1596.     push cur_type
  1597.     call setctype
  1598.  
  1599.     This procedure sets the type of the cursor.  The format
  1600.     is: 0XXYYh, where XX is the starting line (0-13) and YY
  1601.     is the ending line (0-13).
  1602.  
  1603.   ────────── getctype           Get Cursor Type
  1604.  
  1605.     call getctype
  1606.     ; AX = cursor type
  1607.  
  1608.     This procedure returns the current cursor type.  The
  1609.     format is: 0XXYYh, where XX is the starting line (0-13)
  1610.     and YY is the ending line (0-13).
  1611.  
  1612.   ────────── setch              Set Character
  1613.  
  1614.     push x y
  1615.     push char
  1616.     call setch
  1617.  
  1618.     This procedure sets the character at (x, y) to 'char'.
  1619.     The output is clipped to the current window.
  1620.  
  1621.   ────────── setat              Set Attribute
  1622.  
  1623.     push x y
  1624.     push attr
  1625.     call setat
  1626.  
  1627.     This procedure sets the attribute at (x, y) to 'attr'.
  1628.     The output is clipped to the current window.
  1629.  
  1630.   ────────── setcha             Set Char & Attr.
  1631.  
  1632.     push x y
  1633.     push char
  1634.     push attr
  1635.     call setcha
  1636.  
  1637.     This procedure sets the character at (x, y) to 'char',
  1638.     and the attribute to 'attr'.  The output is clipped to
  1639.     the current window.
  1640.  
  1641.   ────────── readcha            Read Char & Attr.
  1642.  
  1643.     push x y
  1644.     call readcha
  1645.     ; AL = char, AH = attr
  1646.  
  1647.     This procedure returns the character and attribute
  1648.     at (x, y).
  1649.  
  1650.   ────────── tputs              Put String at (X, Y)
  1651.  
  1652.     push x y
  1653.     push offset string
  1654.     call tputs
  1655.  
  1656.     This procedure prints 'string' at (x, y).  Output is
  1657.     clipped to the current window.  Output will not wrap
  1658.     around lines.  Control characters will be displayed
  1659.     literally.
  1660.  
  1661.   ────────── tprintf            Print Formatted String at (X, Y)
  1662.  
  1663.     push x y
  1664.     push offset fmtstr
  1665.     push offset arglist
  1666.     call tprintf
  1667.  
  1668.     This procedure prints a formatted string at (x, y).
  1669.     It is equivalent to a 'sprintf' followed by 'tputs'.
  1670.     See 'sprintf' and 'tputs' for more information.
  1671.  
  1672.   ────────── getline            Get Line of Text
  1673.  
  1674.     push x y
  1675.     push offset buffer
  1676.     push min
  1677.     push max
  1678.     call getline
  1679.  
  1680.     This procedure inputs a line of text from the user.
  1681.     A field is drawn at (x, y) extending for (max - 1)
  1682.     characters, and the string is input there.  Full
  1683.     editing, i.e. insert/delete, etc., is supported.
  1684.     A string of minimum 'min' and maximum (max - 1)
  1685.     characters will be put into 'buffer'.
  1686.  
  1687.   ────────── setglchar          Set Char for 'getline'
  1688.  
  1689.     push char
  1690.     call setglchar
  1691.  
  1692.     This sets the character used to clear the input field in
  1693.     'getline'.  The default value is a space (20h).  Another
  1694.     useful value is the small bullet (0FAh).
  1695.  
  1696.   ────────── gettext            Get Block of Text
  1697.  
  1698.     push offset buffer
  1699.     push x1 y1
  1700.     push x2 y2
  1701.     call gettext
  1702.  
  1703.     This procedure captures a rectangular block of text into
  1704.     'buffer'.  No clipping is performed.
  1705.  
  1706.   ────────── puttext            Put Block of Text
  1707.  
  1708.     push offset buffer
  1709.     push x1 y1
  1710.     call puttext
  1711.  
  1712.     This procedure displays a rectangular block of text from
  1713.     'buffer' at (x1, y1).  Output is clipped to the current
  1714.     window.
  1715.  
  1716.   ────────── movetext           Move Block of Text
  1717.  
  1718.     push x1 y1
  1719.     push x2 y2
  1720.     push x y
  1721.     call movetext
  1722.  
  1723.     This procedure moves a rectangular block of text from
  1724.     (x1, y1)-(x2, y2) to (x, y).  If the blocks overlap,
  1725.     it will be handled correctly.  No clipping is performed
  1726.     and the window relative flag is ignored.
  1727.  
  1728.   ────────── delline            Delete Line
  1729.  
  1730.     push y
  1731.     call delline
  1732.  
  1733.     This procedure deletes a line (at 'y') from the current
  1734.     window.  All text below the line is scrolled up, and the
  1735.     bottom line is cleared.
  1736.  
  1737.   ────────── insline            Insert Line
  1738.  
  1739.     push y
  1740.     call insline
  1741.  
  1742.     This procedure inserts a line (at 'y') from the current
  1743.     window.  All text below the line is scrolled down, and
  1744.     the inserted line is cleared.
  1745.  
  1746.   ────────── scroll             Scroll Window
  1747.  
  1748.     push dir
  1749.     call scroll
  1750.  
  1751.     This procedure scrolls the current window.  The values
  1752.     for the direction 'dir' are:
  1753.  
  1754.     0       Scroll Up
  1755.     1       Scroll Down
  1756.     2       Scroll Left
  1757.     3       Scroll Right
  1758.  
  1759.  
  1760.   ─────────────────────────────────────────────────────────────
  1761.   ──────── High-Res Text Mode (90x34) Mouse Procedures ────────
  1762.   ─────────────────────────────────────────────────────────────
  1763.  
  1764.   ────────── minit              Initialize Mouse System
  1765.  
  1766.     call minit
  1767.     ; AX = return code
  1768.  
  1769.     This procedure initializes the High-Res Text Mode
  1770.     Mouse Driver.  If an error occurs or the mouse is
  1771.     not found, 0 is returned, otherwise a nonzero value
  1772.     is returned.
  1773.  
  1774.   ────────── mclose             Close Mouse System
  1775.  
  1776.     call mclose
  1777.  
  1778.     This procedure closes the mouse system.
  1779.  
  1780.   ────────── mshow              Show Mouse Cursor
  1781.  
  1782.     call mshow
  1783.  
  1784.     This procedure displays the mouse cursor on the screen.
  1785.  
  1786.   ────────── mhide              Hide Mouse Cursor
  1787.  
  1788.     call mhide
  1789.  
  1790.     This procedure hides the mouse cursor.
  1791.  
  1792.   ────────── mget               Get Mouse Position
  1793.  
  1794.     call mget
  1795.     ; AX = button status
  1796.     ; BX = mouse X position
  1797.     ; CX = mouse Y position
  1798.  
  1799.     This procedure returns the position and status of the
  1800.     mouse.  The format for the button status is:
  1801.  
  1802.     Bit     Meaning
  1803.  
  1804.      0     Left button
  1805.      1     Right button
  1806.      2     Middle button
  1807.  
  1808.   ────────── mgetdn             Get Mouse Presses
  1809.  
  1810.     push button
  1811.     call mgetdn
  1812.     ; AX = press count
  1813.     ; BX = X position at last press
  1814.     ; CX = Y position at last press
  1815.  
  1816.     This procedure returns the status of a particular mouse
  1817.     button, for presses.  The button values are as follows:
  1818.  
  1819.     0       Left button
  1820.     1       Right button
  1821.     2       Middle button
  1822.  
  1823.   ────────── mgetup             Get Mouse Releases
  1824.  
  1825.     push button
  1826.     call mgetup
  1827.     ; AX = release count
  1828.     ; BX = X position at last release
  1829.     ; CX = Y position at last release
  1830.  
  1831.     This procedure returns the status of a particular mouse
  1832.     button, for releases.  See 'mgetup' for button values.
  1833.  
  1834.  
  1835.   ─────────────────────────────────────────────────────────────
  1836.   ──────────── Integrated VGA Graphics Procedures ─────────────
  1837.   ─────────────────────────────────────────────────────────────
  1838.  
  1839.   ────────── initgraph          Initialize Graphics System
  1840.  
  1841.     push mode
  1842.     call initgraph
  1843.  
  1844.     This procedure initializes the graphics system.  'mode'
  1845.     can be 0, 1, or 2, as follows:
  1846.  
  1847.     0       320x200x256     VGA lo-res graphics
  1848.     1       640x480x16      VGA hi-res graphics
  1849.     2       320x400x256     VGA med-res graphics
  1850.  
  1851.   ────────── closegraph         Close Graphics System
  1852.  
  1853.     This procedure closes the graphics system, and returns
  1854.     to the standard text mode.
  1855.  
  1856.   ────────── setgwin            Set Graphics Window
  1857.  
  1858.     push x1 y1
  1859.     push x2 y2
  1860.     call setgwin
  1861.  
  1862.     This procedure sets the graphics clipping window.
  1863.  
  1864.   ────────── cls                Clear Graphics Screen
  1865.  
  1866.     call cls
  1867.  
  1868.     This procedure clears the screen in graphics mode.
  1869.  
  1870.   ────────── clrgwin            Clear Graphics Window
  1871.  
  1872.     call clrgwin
  1873.  
  1874.     This procedure clears the current graphics window (using
  1875.     the current drawing color).
  1876.  
  1877.   ────────── setgcolor          Set Drawing Color
  1878.  
  1879.     push color
  1880.     call setgcolor
  1881.  
  1882.     This procedure sets the current drawing color.
  1883.  
  1884.   ────────── getgcolor          Get Drawing Color
  1885.  
  1886.     call getgcolor
  1887.     ; AX = current color
  1888.  
  1889.     This procedure returns the current drawing color.
  1890.  
  1891.   ────────── putpix             Put Pixel
  1892.  
  1893.     push x y
  1894.     call putpix
  1895.  
  1896.     This procedure puts a pixel at (x, y) in the current
  1897.     drawing color.  Output is clipped to the current window.
  1898.  
  1899.   ────────── getpix             Get Pixel
  1900.  
  1901.     push x y
  1902.     call getpix
  1903.     ; AX = color at (x, y)
  1904.  
  1905.     This procedure returns the color of the pixel at (x, y).
  1906.  
  1907.   ────────── putrow             Put Row of Pixels
  1908.  
  1909.     push x1 x2 y
  1910.     call putrow
  1911.  
  1912.     This procedure puts a row of pixels (basically like a
  1913.     horizontal line) from (x1, y) to (x2, y), in the current
  1914.     drawing color.
  1915.  
  1916.   ────────── line               Draw Line
  1917.  
  1918.     push x1 y1
  1919.     push x2 y2
  1920.     call line
  1921.  
  1922.     This procedure draws a line from (x1, y1) to (x2, y2) in
  1923.     the current drawing color.  Output is clipped to the
  1924.     current window.
  1925.  
  1926.   ────────── rect               Draw Rectangle
  1927.  
  1928.     push x1 y1
  1929.     push x2 y2
  1930.     call rect
  1931.  
  1932.     This procedure draws a rectangle from (x1, y1) to
  1933.     (x2, y2) in the current drawing color.  Output is
  1934.     clipped to the current window.
  1935.  
  1936.   ────────── frect              Draw Filled Rectangle
  1937.  
  1938.     push x1 y1
  1939.     push x2 y2
  1940.     call frect
  1941.  
  1942.     This procedure draws a filled rectangle from (x1, y1)
  1943.     to (x2, y2) in the current drawing color.  Output is
  1944.     clipped to the current window.
  1945.  
  1946.   ────────── outstr             Output String
  1947.  
  1948.     push x y
  1949.     push offset string
  1950.     call outstr
  1951.  
  1952.     This procedure prints 'string' on the screen, starting
  1953.     at (x, y).  Output is clipped to the current window.
  1954.  
  1955.   ────────── getimage           Get Image
  1956.  
  1957.     push offset buffer
  1958.     push x1 y1
  1959.     push x2 y2
  1960.     call getimage
  1961.  
  1962.     This procedure captures a rectangular block of pixels
  1963.     into 'buffer'.  No clipping is performed.
  1964.  
  1965.   ────────── putimage           Put Image
  1966.  
  1967.     push offset buffer
  1968.     push x1 y1
  1969.     call putimage
  1970.  
  1971.     This procedure displays a rectangular block of pixels
  1972.     from 'buffer' at (x1, y1).  Output is clipped to the
  1973.     current window.
  1974.  
  1975.   ────────── circle             Draw Circle
  1976.  
  1977.     push x y rad
  1978.     call circle
  1979.  
  1980.     This procedure draws a circle with center (x, y) and
  1981.     radius 'rad'.  Output is clipped to the current window.
  1982.  
  1983.     The radius specifies the Y radius.  The actual X radius
  1984.     may be different to compensate for the aspect ratio.
  1985.  
  1986.   ────────── ellipse            Draw Ellipse
  1987.  
  1988.     push x y xr yr
  1989.     call ellipse
  1990.  
  1991.     This procedure draws an ellipse with center (x, y) and
  1992.     radii 'xr' and 'yr'.  Output is clipped to the current
  1993.     window.
  1994.  
  1995.   ────────── fcircle            Draw Filled Circle
  1996.  
  1997.     push x y rad
  1998.     call fcircle
  1999.  
  2000.     This procedure draws a filled circle with center (x, y)
  2001.     and radius 'rad'.  Output is clipped to the current
  2002.     window.
  2003.  
  2004.     The radius specifies the Y radius.  The actual X radius
  2005.     may be different to compensate for the aspect ratio.
  2006.  
  2007.   ────────── fellipse           Draw Filled Ellipse
  2008.  
  2009.     push x y xr yr
  2010.     call fellipse
  2011.  
  2012.     This procedure draws a filled ellipse with center (x, y)
  2013.     and radii 'xr' and 'yr'.  Output is clipped to the
  2014.     current window.
  2015.  
  2016.   ────────── triangle           Draw Triangle
  2017.  
  2018.     push x1 y1
  2019.     push x2 y2
  2020.     push x3 y3
  2021.     call triangle
  2022.  
  2023.     This procedure draws a filled triangle with corners at
  2024.     (x1, y1), (x2, y2), and (x3, y3).  Output is clipped to
  2025.     the current window.
  2026.  
  2027.  
  2028.   ─────────────────────────────────────────────────────────────
  2029.   ────────── Virtual Memory Procedures (80386 only) ───────────
  2030.   ─────────────────────────────────────────────────────────────
  2031.  
  2032.   ────────── vminit             Initialize Virtual Memory
  2033.         
  2034.     call vminit
  2035.     ; AX = return value
  2036.  
  2037.     This procedure initializes the virtual memory system.
  2038.     If an error occurs, 0 is returned, otherwise a nonzero
  2039.     value is returned.
  2040.  
  2041.   ────────── vmclose            Close Virtual Memory
  2042.         
  2043.     call vmclose
  2044.  
  2045.     This procedure closes the virtual memory system.
  2046.  
  2047.   ────────── vmread             Read Virtual Memory
  2048.         
  2049.     push offset buffer
  2050.     push vm_offset      ; offset is 32 bits
  2051.     push length
  2052.     call vmread
  2053.     ; AX = return value
  2054.  
  2055.     This procedure reads the block of virtual memory that
  2056.     begins at 'vm_offset' into 'buffer'.  The size of the
  2057.     block is specified by 'length'.  Both the offset and
  2058.     the length must be even.  If an error occurs, 0 is
  2059.     returned, otherwise a nonzero value is returned.
  2060.  
  2061.   ────────── vmwrite            Write Virtual Memory
  2062.         
  2063.     push offset buffer
  2064.     push vm_offset      ; offset is 32 bits
  2065.     push length
  2066.     call vmwrite
  2067.     ; AX = return value
  2068.  
  2069.     This procedure writes data from 'buffer' into virtual
  2070.     memory starting at 'vm_offset'.  The size of the block
  2071.     is specified by 'length'.  Both the offset and the
  2072.     length must be even.  If an error occurs, 0 is returned,
  2073.     otherwise a nonzero value is returned.
  2074.  
  2075.  
  2076.   ─────────────────────────────────────────────────────────────
  2077.   ───────────────── Miscellaneous Procedures ──────────────────
  2078.   ─────────────────────────────────────────────────────────────
  2079.  
  2080.   ────────── cputype            Get CPU Type
  2081.  
  2082.     call cputype
  2083.     ; AX = CPU type
  2084.  
  2085.     This procedure returns the CPU type (0 = 8086, 1 = 186,
  2086.     etc.)  It cannot detect SX/DX variations.
  2087.  
  2088.   ────────── fputype            Get FPU Type
  2089.  
  2090.     call fputype
  2091.     ; AX = FPU type
  2092.  
  2093.     This procedure returns the FPU type (0 = 8087, 1 = 187,
  2094.     etc.)  If there is no FPU, -1 is returned.
  2095.  
  2096.   ────────── crc16              16-Bit CRC
  2097.  
  2098.     push offset buf
  2099.     push count
  2100.     call crc16
  2101.     ; AX = CRC16 value
  2102.  
  2103.     This procedure returns the CRC16 checksum of the block
  2104.     of memory at 'buf' of length 'count'.
  2105.  
  2106.   ────────── crc32              32-Bit CRC
  2107.  
  2108.     push offset buf
  2109.     push count
  2110.     call crc32
  2111.     ; DX:AX = CRC32 value
  2112.  
  2113.     This procedure returns the CRC32 checksum of the block
  2114.     of memory at 'buf' of length 'count'.
  2115.  
  2116.   ────────── atexit             Register Exit Function
  2117.  
  2118.     push offset func
  2119.     call atexit
  2120.  
  2121.     This procedure registers a function for calling on exit.
  2122.     If an error occurs, 0 is returned, otherwise a nonzero
  2123.     value is returned.
  2124.  
  2125.   ────────── bitcnt             Count Bits
  2126.  
  2127.     push number
  2128.     call bitcnt
  2129.     ; AX = number of set bits
  2130.  
  2131.     This procedure returns the number of set bits in an
  2132.     integer.
  2133.  
  2134.   ────────── highbit            Find High Bit
  2135.  
  2136.     push number
  2137.     call highbit
  2138.     ; AX = highest bit
  2139.  
  2140.     This procedure returns the positon of the highest set
  2141.     bit in an integer.  -1 is returned if it is zero.
  2142.  
  2143.   ────────── sqrt               Square Root
  2144.  
  2145.     push num_hi
  2146.     push num_lo
  2147.     call sqrt
  2148.     ; AX = result
  2149.  
  2150.     This procedure returns the square root of a long
  2151.     integer.  The result is a normal integer.  This
  2152.     procedure treats all values as unsigned.
  2153.  
  2154.   ────────── exec               Execute Program
  2155.  
  2156.     push offset progname
  2157.     push offset cmdline
  2158.     call exec
  2159.     ; AX = return code
  2160.  
  2161.     This procedure executes another program as a child
  2162.     process, with arguments in 'cmdline'.  If an error
  2163.     occurs, 0 is returned, otherwise a nonzero value
  2164.     is returned.
  2165.  
  2166.   ────────── rand               Random Number
  2167.  
  2168.     push max
  2169.     call rand
  2170.     ; AX = result
  2171.  
  2172.     This procedure returns a random number below 'max'.
  2173.  
  2174.   ────────── srand              Seed Random Numbers
  2175.  
  2176.     call srand
  2177.  
  2178.     This procedure seeds the random number generator with
  2179.     the system clock.
  2180.  
  2181.   ────────── truerand           True Random Number
  2182.  
  2183.     push max
  2184.     call truerand
  2185.     ; AX = result
  2186.  
  2187.     This procedure returns a true random number below 'max'.
  2188.  
  2189.     This is not a pseudo-random RNG.  This procedure reads
  2190.     random bits of the system timer to generate the numbers,
  2191.     so the number is truly random.  This procedure has been
  2192.     tested for randomness by exhaustively analyzing 140 MB
  2193.     of random data.
  2194.  
  2195.     However, this routine is extremely slow.  It generates
  2196.     only about 760 random numbers per second on a 486DX2/66.
  2197.  
  2198.  
  2199.   ────────── delay              Delay
  2200.  
  2201.     push delaytime
  2202.     call delay
  2203.  
  2204.     This procedure delays for a specified number of
  2205.     milliseconds before returning.
  2206.  
  2207.   ────────── sound              Set Speaker
  2208.  
  2209.     push freq
  2210.     call sound
  2211.  
  2212.     This procedure turns on the speaker at a specified
  2213.     frequency.
  2214.  
  2215.   ────────── nosound            Turn Speaker Off
  2216.  
  2217.     call nosound
  2218.  
  2219.     This procedure turns the speaker off.
  2220.  
  2221.  
  2222. 7.  List of contributors (credits).
  2223.  
  2224.     Author:     Tenie Remmel.
  2225.  
  2226.     Major contributors:
  2227.  
  2228.       Tylisha C. Andersen -- VGA graphics library
  2229.                              Virtual memory system
  2230.  
  2231.     Minor contributors:
  2232.  
  2233.       David Deganchi -- suggested fix for fgetc bug
  2234.       Russell Leidich -- algorithm in 'truerand'
  2235.       Mark J. Restifo -- found redirection bug
  2236.  
  2237.  
  2238. 8.  History of changes.
  2239.  
  2240.   ────────── Version 1.1 Bug Fixes
  2241.  
  2242.     A bug in the 'STDIO' output was fixed.  It used Int 29h,
  2243.     which does not allow redirection.  Int 21h is being used
  2244.     instead.  This was pointed out by Mark J. Restifo.
  2245.  
  2246.     The documentation did not describe the increased-variety
  2247.     colorset used in  High-Res Text Mode.   A list of colors
  2248.     has been added.
  2249.  
  2250.     The random number code had a lot of problems.  Fixed.
  2251.  
  2252.     The procedure  'allocmem' would not allocate the largest
  2253.     block as returned from 'getmfree'.  Fixed.
  2254.  
  2255.     The procedure 'fgets' would crash, because it pushed the
  2256.     wrong number of arguments in calling 'fgetc'.  Fixed.
  2257.  
  2258.     If a file read crossed a buffer boundary, and writes had
  2259.     occurred to the buffer,  the buffer would  be discarded.
  2260.     This was due to the fgetc bug.  Fixed.
  2261.  
  2262.  
  2263.   ────────── Version 1.1 Additions
  2264.  
  2265.     A set of integrated graphics procedures  (using VGA) was
  2266.     added.   They use the  320x200x256, 320x400x256, and the
  2267.     640x480x16 modes.   The graphics procedures were written
  2268.     by Tylisha C. Andersen.
  2269.  
  2270.     Many of the routines  now have an 80386 version.   These
  2271.     are in the files '386LIB?.ASX'.  And yes, they have been
  2272.     optimized for the 80386, not just translated to 32-bit.
  2273.  
  2274.     Several example programs  have been added.   See section
  2275.     10 for more information.
  2276.  
  2277.     Another file access mode (mode 4) has been added.   This
  2278.     mode fails if the file exists.   This is useful when the
  2279.     file must not already exist,  for example using multiple
  2280.     temporary files.  Also, the file routines were optimized
  2281.     and fixed up  (i.e. fixed the fgetc bug).   The speed of
  2282.     the file read routines has been doubled.
  2283.  
  2284.  
  2285.   ────────── Version 2.0 Additions
  2286.  
  2287.     Bit-oriented file  procedures were added.   These can be
  2288.     useful for compression and encryption programs.  Now can
  2289.     anyone contribute some compression routines?
  2290.  
  2291.     A true random number procedure has been added.   This is
  2292.     not a pseudo-random RNG, this one works by reading timer
  2293.     countdown bits.   See the reference entry 'truerand' for
  2294.     more information.
  2295.  
  2296.     CRC routines  have been added for both 16 and 32-bit CRC
  2297.     values.   These routines are not table based.
  2298.  
  2299.     DOS version checking  has been added.   Now, the startup
  2300.     code checks to make sure DOS v4.0 is running.
  2301.  
  2302.     Trigonometric procedures  (sine, cosine, etc.) have been
  2303.     added.   These work on fixed-point numbers.   The method
  2304.     used is Taylor-series (slow, but very accurate).
  2305.  
  2306.   ────────── Version 2.1 Bug Fixes
  2307.  
  2308.     The 80386 code would not load due to an error.  Fixed.
  2309.  
  2310.  
  2311.   ────────── Version 2.2 Additions
  2312.  
  2313.     Ugly constructs such as  'mov es,ax/popa/mov ax,es' have
  2314.     been replaced with cleaner versions, saving a few bytes.
  2315.  
  2316.     A complete virtual memory system providing a simulated
  2317.     infinite address space has been added.  This was written
  2318.     by Tylisha C. Andersen.
  2319.  
  2320.     
  2321.   ────────── Version 2.2 Bug Fixes
  2322.  
  2323.     The 80386 version of nosound() would crash.  Fixed.
  2324.  
  2325.     getdfree() would not return -1 on error.  Fixed.
  2326.  
  2327.  
  2328. 9.  Future additions, bug reporting, etc.
  2329.  
  2330.   Bugs may be reported to the author at:  tjr19@mail.nwlink.com.
  2331.  
  2332.   In the future, a set of wrapper procedures for calling
  2333.   some of the FREELIB routines from 'C' may be provided.
  2334.   Also, a Compact model edition may be added (this means
  2335.   near code but far pointers for data).
  2336.  
  2337.   This is a list of the routines wanted for future addition:
  2338.  
  2339.     (1) VGA graphics mode mouse routines to go with the VGA
  2340.         graphics code.  (16 AND 256 color mode)
  2341.  
  2342.     (2) General data compression: deflate, etc.
  2343.  
  2344.     (3) Low-level disk routines (read/write sector, format
  2345.         floppy).
  2346.  
  2347.     (4) Routines to read and write configuration data from
  2348.         the program's executable file.
  2349.  
  2350.     (5) Inter-procedure jumps, like the 'C' setjmp()/longjmp().
  2351.  
  2352.     (6) Sound card interface routines.
  2353.  
  2354.     (7) Indefinite long arithmetic, 256 bytes at least.
  2355.  
  2356.     (8) Process management and multitasking.
  2357.  
  2358.     (9) Anything else that might be useful!!!
  2359.  
  2360.   Note that encryption routines will NOT be accepted due to
  2361.   possible restrictions on export of encryption material.
  2362.  
  2363.  
  2364. 10.  Description of examples.
  2365.  
  2366.     Several example programs have been provided to demonstrate
  2367.     the capabilities of FREELIB:
  2368.  
  2369.     3XP1            Solves 3X+1 problem.  Demonstrates long integer
  2370.                     arithmetic and numeric output.
  2371.  
  2372.     BIN2HEX         Binary to hexadecimal filter.
  2373.  
  2374.     GRTEST          Simple demo of graphics system, random numbers.
  2375.  
  2376.     HEX2BIN         Hexadecimal to binary filter.
  2377.  
  2378.     SHOWGY          Program to display *.GY files  (16K grayscale).
  2379.                     Does resolution enhancement to 320x200.  Two of
  2380.                     these files are included (FACE.GY, ROSE.GY).
  2381.  
  2382.     SQUASH          Simple executable file compressor,  but it only
  2383.                     works with .COM files.
  2384.  
  2385.     VIEW            File viewer.  Demonstrates Hi-Res Text Mode and
  2386.                     the buffered file-access facilities.  Also uses
  2387.                     memory allocation.
  2388.  
  2389.     ZE, ZD          UUencode replacement, expands files by only 26%
  2390.                     instead of 40% like UUencode does.  ZE encodes,
  2391.                     and ZD decodes.
  2392.  
  2393.  
  2394.     These files can be found in the directory 'PROGS'.  To assemble
  2395.     the example programs, a batch file (REDO_EX.BAT) is provided.
  2396.  
  2397. ──────────────────────────────────────────────────────────────────────
  2398. ──────────────────────────────────────────────────────────────────────
  2399.